﻿#include "FITKNastranAdaptorPSHELL.h"

namespace Nastran
{
FITKNastranAdaptorPSHELL::~FITKNastranAdaptorPSHELL()
{
}

/**
 *  Checks necessary data objects and initializes variables related to file content
 *  Returns true if all necessary data objects are valid and the file content is not empty; otherwise, returns false
 *
 * This function first checks if _caseData, getReader(), and _fileContentCache are null.
 * If any of them are null, it returns false immediately, indicating that further processing cannot be performed.
 *
 * Next, the function retrieves the first line of content from _fileContentCache and parses filePID, fileMID, and fileT
 * based on the line's content format. If the line starts with "PSHELL*", it is parsed with a width of 16 characters;
 * otherwise, it is parsed with a width of 8 characters.
 *
 * Then, the function obtains the SectionManager instance from _caseData and checks if it is null.
 * If it is null, an error message is output and false is returned.
 *
 * The function then attempts to retrieve the corresponding section instance using filePID.
 * If the section already exists, a warning message is output and the existing instance is overwritten;
 * If it does not exist, a new section instance is created and added to the SectionManager.
 *
 * Next, the function obtains the MaterialManager instance from _caseData and checks if it is null.
 * If it is null, an error message is output;
 * If it is not null, the function tries to retrieve the corresponding material instance using fileMID.
 * If the material does not exist, a new material instance is created and added to the MaterialManager.
 *
 * Finally, the material and thickness properties of the section instance are set to the parsed values, and true is
 * returned to indicate success.
 */
bool FITKNastranAdaptorPSHELL::adaptR()
{
    if (nullptr == _caseData || nullptr == getReader() || _fileContentCache.isEmpty())
    {
        return false;
    }

    quint64 fileMID = 0;
    quint64 filePID = 0;
    double fileT = 0;
    QString line = _fileContentCache.head();

    if (line.startsWith("PSHELL*"))
    {
        filePID = line.mid(8 + 16 * 0, 16).toInt();
        fileMID = line.mid(8 + 16 * 1, 16).toInt();
        fileT = line.mid(8 + 16 * 2, 16).toDouble();
    }
    else
    {
        filePID = line.mid(8 * 1, 8).toInt();
        fileMID = line.mid(8 * 2, 8).toInt();
        fileT = line.mid(8 * 3, 8).toDouble();
    }

    auto sectionMager = _caseData->getSectionManager();
    if (nullptr == sectionMager)
    {
        getReader()->consoleMessage(2, "nullptr error for section manager");
        return false;
    }

    Interface::FITKAbaSectionShellHomogeneous *section = nullptr;
    section = dynamic_cast<Interface::FITKAbaSectionShellHomogeneous *>(
        _caseData->getSectionManager()->getDataByName(QString::number(filePID)));

    if (nullptr != section)
    {
        getReader()->consoleMessage(2, "an existed section have same name. now will cover it");
    }
    else
    {
        section = new Interface::FITKAbaSectionShellHomogeneous();
        section->setDataObjectName(QString::number(filePID));
        _caseData->getSectionManager()->appendDataObj(section);
    }

    Interface::FITKAbstractMaterial *materialPtr = nullptr;
    Interface::FITKMaterialManager *materialManager = _caseData->getMaterialManager();

    if (nullptr == materialManager)
    {
        getReader()->consoleMessage(3, "nullptr error for section manager!");
    }
    else
    {
        materialPtr = _caseData->getMaterialManager()->getDataByName(QString::number(fileMID));
        // if material not exists, new one
        if (nullptr == materialPtr)
        {
            materialPtr = new Interface::FITKAbaMaterial();
            materialPtr->setDataObjectName(QString::number(fileMID));
            _caseData->getMaterialManager()->appendDataObj(materialPtr);
            getReader()->consoleMessage(2, QString("There isn't material named %1, create a empty one.").arg(fileMID));
        }
    }
    section->setMaterial(materialPtr->getDataObjectID());
    section->setThickness(fileT);
    return true;
}

bool FITKNastranAdaptorPSHELL::adaptW()
{
    Interface::FITKAbstractSectionManager* sectionMgr = _caseData->getSectionManager();
    Interface::FITKMaterialManager *materialManager = _caseData->getMaterialManager();
    if (sectionMgr == nullptr || materialManager == nullptr) return false;
    const int count = sectionMgr->getDataCount();
    _fileContentCache.append("$$");
    _fileContentCache.append("$$  PSHELL Data");
    for (int index = 0; index < count; index++)
    {
        Interface::FITKAbaSectionShellHomogeneous *section = dynamic_cast<Interface::FITKAbaSectionShellHomogeneous *>(sectionMgr->getDataByIndex(index));
        if (section == nullptr) continue;
        //PID
        QString filePID = section->getDataObjectName();
        //MID
        Interface::FITKAbstractMaterial *materialPtr = _caseData->getMaterialManager()->getDataByID(section->getMaterialID());
        if (materialPtr == nullptr) continue;
        QString fileMID = materialPtr->getDataObjectName();
        //T
        double fileT = section->getThickness();
        //
        _fileContentCache.append("$");
        _fileContentCache.append("$HMNAME PROP                  "+ filePID +"\"property9_"+ filePID +"\" 4");
        _fileContentCache.append("$HWCOLOR PROP                 "+ filePID +"       5");
        QString tempStr;
        tempStr.append("PSHELL  ");
        tempStr.append(Interface::FITKAbstractTextWriter::int2String(filePID.toInt(), 8));
        tempStr.append(Interface::FITKAbstractTextWriter::int2String(fileMID.toInt(), 8));
        tempStr.append(Value2String(fileT));
        tempStr.append(Interface::FITKAbstractTextWriter::int2String(fileMID.toInt(), 8));//MID2==MID1
        tempStr.append("        ");//12I/T**3 暂为空
        tempStr.append(Interface::FITKAbstractTextWriter::int2String(fileMID.toInt(), 8));//MID3==MID1
        _fileContentCache.append(tempStr);
    }
    return true;
}

void FITKNastranAdaptorPSHELL::setCaseData(AbaqusData::FITKDataCase *caseData)
{
    _caseData = caseData;
}

void FITKNastranAdaptorPSHELL::setFileContentCache(QQueue<QString> cache)
{
    _fileContentCache = cache;
}
void FITKNastranAdaptorPSHELL::getFileContentCache(QQueue<QString>& cache)
{
    cache = _fileContentCache;
}
} // namespace Nastran
